﻿using System;
using System.Collections.Generic;
using Android.App;
using Android.Views;
using Moven.Gestures;

namespace Moven.Droid.Gestures
{
	public class GestureTouchDispatcher
	{
		Activity _activity { get; set; }

		Dictionary<MotionEvent, GestureMotionEvent> _delayedMotionEvents = new Dictionary<MotionEvent, GestureMotionEvent>();

		public GestureTouchDispatcher(Activity activity)
		{
			_activity = activity;
		}

		public bool DispatchTouchEvent(MotionEvent ev)
		{
			bool wasDelayed = _delayedMotionEvents.ContainsKey(ev);
			if (wasDelayed)
			{
				Console.WriteLine("was delayed event - processing now " + ev);
				var gestureEvent = _delayedMotionEvents[ev];
				_delayedMotionEvents.Remove(ev);
				var restoredEvent = gestureEvent.GetCachedEvent();
				_activity.DispatchTouchEvent(restoredEvent);
				var handled = _delayedMotionEvents.Remove(restoredEvent);
				return handled;
			}
			var gestureMotionEvent = new GestureMotionEvent(ev);
			//find if there's a view container with a gesture, which is currently on the screen.
			foreach (var recognizer in NativeGestureCoordinator.GroupRecognizers)
			{
				var nativeRecognizer = recognizer.NativeGestureRecognizer as BaseNativeGestureRecognizer;
				//				Console.WriteLine ("checkign gesture touch");
				nativeRecognizer.ProcessGestureMotionEvent(gestureMotionEvent);
				gestureMotionEvent.IsConsumed = GetIsConsumedState(nativeRecognizer.State);
				wasDelayed = wasDelayed || gestureMotionEvent.IsMarkedForDelay;
			}

			if (gestureMotionEvent.IsConsumed && gestureMotionEvent.IsCancelled)
			{
				ev.Action = MotionEventActions.Cancel;
			}
			if (gestureMotionEvent.IsMarkedForDelay)
			{
				_delayedMotionEvents[ev] = gestureMotionEvent;
			}
			else if (wasDelayed)
			{
				//it's been released from being delayed
				_activity.DispatchTouchEvent(ev);
			}
			return gestureMotionEvent.IsConsumed;
		}


		bool GetIsConsumedState(GestureRecognizerState state)
		{
			return state == GestureRecognizerState.Ended || state == GestureRecognizerState.Began ||
			state == GestureRecognizerState.Recognized || state == GestureRecognizerState.Changed;
		}
	}
}
